package test;

import static org.junit.Assert.*;
import hospital.Hospital;

import movement.Location;

import org.junit.*;

import unit.Ambulance;
import unit.Garage;
import unit.Unit;

import dispatch.DispatchCenter;
import dispatch.Dispatcher;
import dispatch.Operator;
import emergency.*;

public class testDispatchCenter {
	DispatchCenter center;
	DispatchCenter centerLocation;

	private Garage garage;
	Location location,l2;
	@SuppressWarnings("unused")
	private Emergency impossibleFireEmergency, publicdisturbance,
			trafficaccident, robbery;
	
	Unit ambu1, ambu2, ambu3, ambu4;

	@Test
	public void getEmergenciesFromType(){
		assertEquals(1,center.getEmergenciesFromType("fire").size());
		assertEquals(1,center.getEmergenciesFromType("publicdisturbance").size());
		assertEquals(1,center.getEmergenciesFromType("robbery").size());
		assertEquals(1,center.getEmergenciesFromType("trafficaccident").size());
	}
	
	@Test
	public void getHospitals(){
		assertEquals(0,center.getHospitals().size());
		center.getGarage().getHospitalboard().addHospital(new Hospital("GBH", new Location(1,1,"d")));
		assertEquals(1,center.getHospitals().size());
	}
	
	@Test
	public void getHospitalsLocation(){
		Hospital h1 = new Hospital("GBH", new Location(1,1,"d"));
		Hospital h2 = new Hospital("GBH2", new Location(10,10,"d2"));
		
		center.getGarage().getHospitalboard().addHospital(h1);
		center.getGarage().getHospitalboard().addHospital(h2);
		
		assertEquals(h1, center.getHospitals(new Location(2,2,"d")).get(0));
		assertEquals(h2, center.getHospitals(new Location(2,2,"d")).get(1));
	}
	
	@Before
	public void setUp() throws Exception {
		location = new Location(30, 30, "DC Location");

		l2 = new Location(35, 35, "DC Location2");
		center = new DispatchCenter("center", location,
				new Location(60, 60, "GarageLocation"));
		centerLocation = new DispatchCenter("CenterWithLocation", l2,
				new Location(60, 60, "GarageLocation"));

		publicdisturbance = new PublicDisturbance(new Location(10, 10,
				"Brussel"), Severity.NORMAL, center, 4);
		trafficaccident = new TrafficAccident(new Location(10, 10, "Brussel"),
				Severity.BENIGN, center, 3, 2);
		robbery = new Robbery(new Location(10, 10, "Brussel"), Severity.NORMAL,
				center, true, true);

		// impossible to assign ( not enough units in garage )
		impossibleFireEmergency = new Fire(new Location(10, 10, "Brussel"),
				Severity.NORMAL, center, Fire.Size.HOUSE, false, 20, 3);
				
		garage = new Garage(location, center);
		
    	ambu1 = new Ambulance("Ambulance-1", 0,garage);
    	ambu2 = new Ambulance("Ambulance-2", 0,garage);
    	ambu3 = new Ambulance("Ambulance-3", 0,garage);
    	ambu4 = new Ambulance("Ambulance-4", 0,garage);

	}

	@Test
	public void testAddDispatcher() {
		assertEquals(center.getDispatchersClone().size(), 0);
		Dispatcher d1 = new Dispatcher("Dispatcher1");
		Dispatcher d2 = new Dispatcher("Dispatcher2");
		center.addDispatcher(d2);
		assertEquals(center.getDispatchersClone().size(), 1);
		center.addDispatcher(d1);
		assertEquals(center.getDispatchersClone().size(), 2);

		// test getDispatcher(String name)
		assertEquals(center.getDispatcher("Dispatcher1"), d1);
		assertEquals(center.getDispatcher("Dispatcher2"), d2);
	}
	
	@Test(expected = IllegalArgumentException.class)
	public void testAddInvalidDispatcher() {
		// dispatchers are invalid if their name is InValid
		Dispatcher InvalidDispatcher = new Dispatcher("InValid");
		center.addDispatcher(InvalidDispatcher);
	}
	
	@Test
	public void testAddOperator() {
		assertEquals(center.getOperatorsClone().size(), 0);
		Operator d1 = new Operator("Operator1");
		Operator d2 = new Operator("Operator2");
		
		center.addOperator(d1);
		assertEquals(center.getOperatorsClone().size(), 1);
		center.addOperator(d2);
		assertEquals(center.getOperatorsClone().size(), 2);

		// test getDispatcher(String name)
		assertEquals(center.getOperator("Operator1"), d1);
		assertEquals(center.getOperator("Operator2"), d2);
	}

	@Test
	public void testConstructor(){
		assertEquals(center.getGarage().getLocation().getX(),60);
		assertEquals(center.getGarage().getLocation().getY(),60);
		assertEquals(center.getLocation(), location);
		
		assertEquals(0,center.getDispatchersClone().size());
		assertEquals(0,center.getOperatorsClone().size());
		assertEquals("center", center.getName());
		
		//4 emergencies created and added to DC
		assertEquals(4,center.getEmergencyboard().getEmergencies().size());
	}
	

	@SuppressWarnings("unused")
	@Test (expected=IllegalArgumentException.class)
	public void testConstructorInvalidLocation(){
		DispatchCenter c = new DispatchCenter("Jup", null, new Location(10,10,"d"));
	}

	@SuppressWarnings("unused")
	@Test(expected = IllegalArgumentException.class)
	public void testCreateDispatchCenterNullGarageLocation() {
		DispatchCenter dc = new DispatchCenter("DC1", location, null);
	}

	@SuppressWarnings("unused")
	@Test(expected = IllegalArgumentException.class)
	public void testCreateDispatchCenterNullLocation() {
		DispatchCenter dc = new DispatchCenter("DC2", null, location);
	}
	
	@SuppressWarnings("unused")
	@Test(expected = IllegalArgumentException.class)
	public void testCreateDispatchCenterNullName() {
		DispatchCenter dc = new DispatchCenter(null, location, location);
	}
	
	@Test
	public void testGetDispatcher() {
		Dispatcher d2 = new Dispatcher("Dispatcher2");
		center.addDispatcher(d2);
		assertEquals(d2,center.getDispatcher("Dispatcher2"));
	}


	@Test
	public void testGetOperator() {
		Operator o2 = new Operator("Operator2");
		center.addOperator(o2);
		assertEquals(o2,center.getOperator("Operator2"));
	}
	
	@Test
	public void testGettersAndSetters() {
		assertEquals(centerLocation.getName(), "CenterWithLocation");
		assertEquals(center.getName(), "center");

		assertEquals(center.getDispatchersClone().size(), 0);
		assertEquals(centerLocation.getDispatchersClone().size(), 0);

		assertEquals(center.getOperatorsClone().size(), 0);
		assertEquals(centerLocation.getOperatorsClone().size(), 0);

		assertEquals(center.getGarage().getDispatchcenter(), center);
		assertEquals(centerLocation.getGarage().getDispatchcenter(),
				centerLocation);

		assertEquals(center.getLocation().getName(),"DC Location");
		assertEquals(center.getLocation().getX(), 30);
		assertEquals(center.getLocation().getY(), 30);
		assertEquals(centerLocation.getLocation(), l2);

		assertEquals(center.getEmergencyboard().getDispatchcenter(), center);
		assertEquals(centerLocation.getEmergencyboard().getDispatchcenter(),
				centerLocation);

		assertEquals(center.getHospitals().size(), 0);
		assertEquals(centerLocation.getHospitals().size(), 0);

	}
	
	@Test(expected = IllegalArgumentException.class)
	public void testGetUnknownDispatcher() {
		Dispatcher d2 = new Dispatcher("Dispatcher2");
		center.addDispatcher(d2);
		center.getDispatcher("Jannie");
	}
	
	@Test(expected = IllegalArgumentException.class)
	public void testGetUnknownOperator() {
		Operator o2 = new Operator("Operator2");
		center.addOperator(o2);
		center.getOperator("Jannie");
	}
	
	@Test(expected = IllegalArgumentException.class)
	public void testInvalidOperator() {
		// operators are invalid if their name is 'InValid'
		Operator invalidOperator = new Operator("InValid");
		center.addOperator(invalidOperator);
	}
}
